Linphone Python Wrapper
Installation
Download either a stable version or a snapshot of the liblinphone python wrapper.
Linux
Install some dependencies first:
sudo easy_install pip
sudo pip install wheel
sudo pip install --upgrade pip
Then install the linphone python wrapper using pip (replace the file name by the one you downloaded):
To check if the installation was successful, launch a python shell, and in the python prompt (>>>), enter:
If you get no error message and an other prompt >>> then everything is ok! Otherwise you are welcome to explain the error you are having of the linphone-users mailing-list.
Getting started
Here is a simple python program that performs the functionality of a security camera.
import linphone
import logging
import signal
import time
class SecurityCamera:
def __init__(self, username='', password='', whitelist=[], camera='', snd_capture='', snd_playback=''):
self.quit = False
self.whitelist = whitelist
callbacks = linphone.Factory.get().create_core_cbs()
callbacks.call_state_changed = self.call_state_changed
# Configure the linphone core
logging.basicConfig(level=logging.INFO)
signal.signal(signal.SIGINT, self.signal_handler)
linphone.set_log_handler(self.log_handler)
self.core = linphone.Factory.get().create_core(callbacks, None, None)
self.core.max_calls = 1
self.core.echo_cancellation_enabled = False
self.core.video_capture_enabled = True
self.core.video_display_enabled = False
self.core.nat_policy.stun_server = 'stun.linphone.org'
self.core.nat_policy.ice_enabled = True
if len(camera):
self.core.video_device = camera
if len(snd_capture):
self.core.capture_device = snd_capture
if len(snd_playback):
self.core.playback_device = snd_playback
# Only enable PCMU and PCMA audio codecs
for codec in self.core.audio_codecs:
if codec.mime_type == "PCMA" or codec.mime_type == "PCMU":
self.core.enable_payload_type(codec, True)
else:
self.core.enable_payload_type(codec, False)
# Only enable VP8 video codec
for codec in self.core.video_codecs:
if codec.mime_type == "VP8":
self.core.enable_payload_type(codec, True)
else:
self.core.enable_payload_type(codec, False)
self.configure_sip_account(username, password)
def signal_handler(self, signal, frame):
self.core.terminate_all_calls()
self.quit = True
def log_handler(self, level, msg):
method = getattr(logging, level)
method(msg)
def call_state_changed(self, core, call, state, message):
if state == linphone.CallState.IncomingReceived:
if call.remote_address.as_string_uri_only() in self.whitelist:
params = core.create_call_params(call)
core.accept_call_with_params(call, params)
else:
core.decline_call(call, linphone.Reason.Declined)
chat_room = core.get_chat_room_from_uri(self.whitelist[0])
msg = chat_room.create_message(call.remote_address_as_string + ' tried to call')
chat_room.send_chat_message(msg)
def configure_sip_account(self, username, password):
# Configure the SIP account
proxy_cfg = self.core.create_proxy_config()
proxy_cfg.identity_address = self.core.create_address('sip:{username}@sip.linphone.org'.format(username=username))
proxy_cfg.server_addr = 'sip:sip.linphone.org;transport=tls'
proxy_cfg.register_enabled = True
self.core.add_proxy_config(proxy_cfg)
auth_info = self.core.create_auth_info(username, None, password, None, None, 'sip.linphone.org')
self.core.add_auth_info(auth_info)
def run(self):
while not self.quit:
self.core.iterate()
time.sleep(0.03)
def main():
cam = SecurityCamera(username='raspberry', password='pi', whitelist=['sip:trusteduser@sip.linphone.org'], camera='V4L2: /dev/video0', snd_capture='ALSA: USB Device 0x46d:0x825')
cam.run()
main()
Basically, it:
- registers on sip.linphone.org with the account 'raspberry' and the password 'pi' (hint: change these values for you own ones in the main() function)
- listens for incoming calls
- automatically answers to an incoming call if it comes from one of the SIP addresses in the whitelist (in this case from 'sip:trusteduser@sip.linphone.org')
- declines the incoming calls coming from other SIP addresses
- sends a chat message to the first SIP address in the whitelist (considered as the administrator) if someone that is not authorized to do so calls the security camera
Other interesting things to note are that:
- the echo canceller is disabled because it uses a lot of CPU power which the Raspberry PI does not have. And it is not really useful for that use case.
- the only audio codecs enabled are PCMU and PCMA for the same reason. Other codecs such as speex or opus require too much CPU if we want to also have the video.
- the VP8 codec is used for video.
- the camera device, the sound capture device and the sound playback device are configurable. Just change the corresponding values in the main() function. The available values are listed in the logs when starting the program.
This is just a basic code example that can be greatly improved and to which a lot of features can be added. For example, you could perform some actions when receiving a chat message.
The API documentation can be found at http://pythonhosted.org/linphone/.
You are more than welcome to exchange all the useful feature you achieve on the linphone-users mailing-list!